package psbc.daily.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import psbc.daily.context.BaseContext;
import psbc.daily.entity.MyLog;
import psbc.daily.entity.dto.SearchDto;
import psbc.daily.mapper.MyLogMapper;
import psbc.daily.service.MyLogService;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class MyLogServiceImpl extends ServiceImpl<MyLogMapper, MyLog> implements MyLogService {

    @Resource
    private MyLogMapper myLogMapper;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 获取所有日志
     * @param userId 用户id
     * @return 用户id的所有日志
     */
    @Override
    public List<MyLog> getAll(Long userId) {
        if (userId != null) {
            //先查缓存
            Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries("log:userId:" + userId);

            if (entries == null || entries.isEmpty()) {
                //缓存没有 查询数据库
                QueryWrapper<MyLog> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("user_id", userId);
                List<MyLog> myLogs = myLogMapper.selectList(queryWrapper);
                //数据库查询到 写缓存 返回数据
                if (!myLogs.isEmpty()) {
                    for (MyLog myLog : myLogs) {
                        stringRedisTemplate.opsForHash().put("log:userId:" + userId, String.valueOf(myLog.getId()), JSON.toJSONString(myLog));
                    }
                    return myLogs;
                }

                //数据库没有返回错误
                return null;
            }
            // 缓存命中，将 JSON 字符串列表转换为 MyLog 对象列表
            return entries.values().stream()
                    .map(json -> JSON.parseObject((String) json, MyLog.class))
                    .collect(Collectors.toList());
        }
        return null;
    }

    /**
     * 新增日志
     * @param record 日志
     * @return 影响行数
     */
    @Override
    public int addLog(MyLog record) {
        //新增
        int insert = myLogMapper.insert(record);
        if (insert > 0){
            Long userId = Long.valueOf(record.getUserId());

            stringRedisTemplate.opsForHash().put("log:userId:" + userId, String.valueOf(record.getId()), JSON.toJSONString(record));
        }
        return insert;
    }

    /**
     * 根据id查询日志
     * @param id 日志id
     * @return 日志对象
     */
    @Override
    public MyLog selectById(int id) {
        //先查缓存
        Long userId = BaseContext.getCurrentId();
        Object object = stringRedisTemplate.opsForHash().get("log:userId:" + userId, String.valueOf(id));
        if (object != null) {
            // 缓存命中，将 JSON 字符串转换为 MyLog 对象
            return JSON.parseObject((String) object, MyLog.class);
        } else {
            // 缓存未命中，查询数据库
            QueryWrapper<MyLog> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("id", id);
            MyLog myLog = myLogMapper.selectOne(queryWrapper);

            if (myLog != null) {
                // 将查询结果写入缓存
                String logJson = JSON.toJSONString(myLog);
                stringRedisTemplate.opsForHash().put("log:userid:" + userId, String.valueOf(id), logJson);
                return myLog;
            }
            return null;
        }
    }


    @Override
    public List<MyLog> selectByDate(SearchDto searchDto, Long currentId) throws ParseException {
        String[] recordDate = searchDto.getRecordDate();
        Integer categoryId = searchDto.getCategoryId();
        //分类 日期都为空
        if (categoryId == null && recordDate.length == 0){
            return null;
        }

        //分类为空
        if (categoryId == null && recordDate.length>0) {
            //先查缓存
            Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries("log:userId:" + currentId);
            if (entries == null || entries.isEmpty()) {
                //缓存没有 查询数据库
                QueryWrapper<MyLog> queryWrapper = new QueryWrapper<>();
                queryWrapper.between("record_date", recordDate[0], recordDate[1]);
                queryWrapper.eq("user_id", currentId);

                //写入缓存
                for (MyLog myLog : myLogMapper.selectList(queryWrapper)) {
                    stringRedisTemplate.opsForHash().put("log:userId:" + currentId, String.valueOf(myLog.getId()), JSON.toJSONString(myLog));
                }
                return myLogMapper.selectList(queryWrapper);
            }

            List<MyLog> myLogs = new ArrayList<>();
            List<MyLog> myLogList = entries.values().stream()
                    .map(json -> JSON.parseObject((String) json, MyLog.class))
                    .collect(Collectors.toList());

            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            Date startDate = dateFormat.parse(recordDate[0]);
            Date endDate = dateFormat.parse(recordDate[1]);

            for (MyLog myLog : myLogList) {
                String logDate = myLog.getRecordDate();
                Date date = dateFormat.parse(logDate);
                if (!date.before(startDate) && !date.after(endDate)) {
                    myLogs.add(myLog);
                }
            }
            return myLogs;
        }

        //日期为空
        if (recordDate.length==0 && categoryId != null) {
            //先查缓存
            Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries("log:userId:" + currentId);
            if (entries == null || entries.isEmpty()) {
                //缓存没有 查询数据库
                QueryWrapper<MyLog> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("category_id", categoryId);
                queryWrapper.eq("user_id", currentId);

                //写入缓存
                for (MyLog myLog : myLogMapper.selectList(queryWrapper)) {
                    stringRedisTemplate.opsForHash().put("log:userId:" + currentId, String.valueOf(myLog.getId()), JSON.toJSONString(myLog));
                }
                return myLogMapper.selectList(queryWrapper);
            }

            List<MyLog> myLogs = new ArrayList<>();
            List<MyLog> myLogList = entries.values().stream()
                    .map(json -> JSON.parseObject((String) json, MyLog.class))
                    .collect(Collectors.toList());
            for (MyLog myLog : myLogList) {
                if (myLog.getCategoryId() == categoryId) {
                    myLogs.add(myLog);
                }
            }
            return myLogs;
        }

        //都不为空
        if (categoryId != null && recordDate.length > 0){
            log.info("categoryId:{},recordDate:{}",categoryId,recordDate);
            //先查缓存
            Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries("log:userId:" + currentId);
            if (entries == null || entries.isEmpty()) {
                //缓存没有 查询数据库
                QueryWrapper<MyLog> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("category_id", categoryId);
                queryWrapper.between("record_date", recordDate[0], recordDate[1]);
                queryWrapper.eq("user_id",currentId);
                return myLogMapper.selectList(queryWrapper);
            }

            List<MyLog> myLogs = new ArrayList<>();
            List<MyLog> myLogList = entries.values().stream()
                    .map(json -> JSON.parseObject((String) json, MyLog.class))
                    .collect(Collectors.toList());
            for (MyLog myLog : myLogList) {
                String logDate = myLog.getRecordDate();
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                Date startDate = dateFormat.parse(recordDate[0]);
                Date endDate = dateFormat.parse(recordDate[1]);
                Date date = dateFormat.parse(logDate);
                if (!date.before(startDate) && !date.after(endDate) && myLog.getCategoryId() == categoryId) {
                    myLogs.add(myLog);
                }
            }
            return myLogs;
        }
        return null;
    }

    /**
     * 根据日期删除日志
     * @param recordDate 日志日期
     * @return 影响行数
     */
    @Override
    public int deleteByDate(String recordDate) {
        Long userId = BaseContext.getCurrentId();
        //删除数据
        QueryWrapper<MyLog> myLogQueryWrapper = new QueryWrapper<>();
        myLogQueryWrapper.eq("record_date",recordDate);
        myLogQueryWrapper.eq("user_id",userId);
        MyLog myLog = myLogMapper.selectOne(myLogQueryWrapper);
        int delete = myLogMapper.delete(myLogQueryWrapper);
        //更新缓存
        stringRedisTemplate.opsForHash().delete("log:userId:" + userId, myLog.getId());
        return delete;
    }

    /**
     * 根据id删除日志
     * @param id 日志id
     * @return 影响行数
     */
    @Override
    public int deleteById(int id) {
        Long userId = BaseContext.getCurrentId();
        //更新缓存
        stringRedisTemplate.opsForHash().delete("log:userId:" + userId, String.valueOf(id));

        //删除数据
        QueryWrapper<MyLog> myLogQueryWrapper = new QueryWrapper<>();
        myLogQueryWrapper.eq("id",id);
        int delete = myLogMapper.delete(myLogQueryWrapper);


        return delete;
    }

    @Override
    public int updateLog(MyLog myLog) {
        //更新日志信息
        int update = myLogMapper.updateById(myLog);

        //更新缓存
        stringRedisTemplate.opsForHash().put("log:userId:" + myLog.getUserId(), String.valueOf(myLog.getId()),JSON.toJSONString(myLog));

        return update;
    }
}
